#include "hls_m3u8_message.h"

#include "./../write_read_module/buffer.h"

#include <cstdlib>
#include <cstring>
#include <vector>

HlsM3U8Message::HlsM3U8Message()
{
    m_flag            = "#EXTM3U";
    m_has_ext_endlist = true;
}

void HlsM3U8Message::PlayListType(const std::string & type)
{
    m_playlist_type = type;
}

void HlsM3U8Message::TargetDuration(const std::string & duration)
{
    m_target_duration = duration;
}

void HlsM3U8Message::Version(const std::string & version)
{
    m_version = version;
}

void HlsM3U8Message::MediaSequence(const std::string & sequence)
{
    m_media_sequence = sequence;
}

void HlsM3U8Message::UriIndex(const std::string & extinf, const std::string & uri)
{
    m_uri_vec.push_back({.m_extinf = extinf, .m_index_uri = uri});
}

std::string HlsM3U8Message::PlayListType() const
{
    return m_playlist_type;
}

double HlsM3U8Message::TargetDuration() const
{
    return atof(m_target_duration.c_str());
}

int HlsM3U8Message::Version() const
{
    return atoi(m_version.c_str());
}

int HlsM3U8Message::MediaSequence() const
{
    return atoi(m_media_sequence.c_str());
}

std::vector<HlsM3U8Message::Uri> & HlsM3U8Message::UriIndex()
{
    return m_uri_vec;
}

void HlsM3U8Message::UpdateExtEndList(bool state)
{
    m_has_ext_endlist = state;
}

bool HlsM3U8Message::HasExtEndList() const
{
    return m_has_ext_endlist;
}

void HlsM3U8Message::Clear()
{
    m_has_ext_endlist = false;
    m_uri_vec.clear();
    m_playlist_type.clear();
    m_target_duration.clear();
    m_version.clear();
    m_media_sequence.clear();
    m_stream_info_vec.clear();
}

void HlsM3U8Message::StreamInfoData(HlsM3U8Message::StreamInfo & stream_info)
{
    m_stream_info_vec.push_back(stream_info);
}

std::vector<HlsM3U8Message::StreamInfo> & HlsM3U8Message::StreamInfoData()
{
    return m_stream_info_vec;
}

int HlsM3U8Message::IncludeStreamInfo() const
{
    return (!m_stream_info_vec.empty() && !m_uri_vec.empty());
}

int HlsM3U8MessageUtil::BuildM3U8Content(HlsM3U8Message * message, const std::string & abs_media_path, std::string & content)
{
    WriteBuffer buffer = {};
    buffer.PrintFmt("#EXTM3U\n");
    buffer.PrintFmt("#EXT-X-PLAYLIST-TYPE:%s\n", message->PlayListType().c_str());
    buffer.PrintFmt("#EXT-X-TARGETDURATION:%.2lf\n", message->TargetDuration());
    buffer.PrintFmt("#EXT-X-VERSION:%d\n", message->Version());
    buffer.PrintFmt("#EXT-X-MEDIA-SEQUENCE:%d\n", message->MediaSequence());
    const auto & uri_data = message->UriIndex();
    for (auto & item : uri_data)
    {
        buffer.PrintFmt("%s\n", item.m_extinf.c_str());
        buffer.PrintFmt("%s%s%s\n", abs_media_path.c_str(), abs_media_path.empty() ? "" : "/", item.m_index_uri.c_str());
    }
    buffer.PrintFmt("#EXT-X-ENDLIST\n");
    content = std::string(reinterpret_cast<const char *>(buffer.BufferData()), buffer.BufferDataSize());
    return buffer.BufferDataSize();
}

std::string HlsM3U8MessageUtil::ComposePath(const std::string & base, const std::string & path)
{
    return base + "/" + path;
}

